package com.dailyblue.java.project.smbms.user.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dailyblue.java.commons.util.DateUtil;
import com.dailyblue.java.commons.util.JsonResult;
import com.dailyblue.java.commons.util.ResultCode;
import com.dailyblue.java.commons.util.ResultTool;
import com.dailyblue.java.project.smbms.user.bean.User;
import com.dailyblue.java.project.smbms.user.config.JwtConfig;
import com.dailyblue.java.project.smbms.user.feign.RoleFeign;
import com.dailyblue.java.project.smbms.user.mapper.UserMapper;
import com.dailyblue.java.project.smbms.user.service.UserService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private RoleFeign roleFeign;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public JsonResult findAllUser() {
        // 获取到所有用户信息，缺少：年龄，性别，角色
        List<User> list = list();
        unpackingAndPacking(list);
        return ResultTool.success(list);
    }

    @Cacheable(cacheNames = "findUser", key = "#page")
    public JsonResult findUser(int page) {
        log.info("看是查询page:{}页数据", page);
        PageHelper.startPage(page, 5);
        List<User> list = list();
        unpackingAndPacking(list);
        PageInfo<User> pageInfo = new PageInfo<>(list);
        return ResultTool.success(pageInfo);
    }

    @Cacheable(cacheNames = "findUserByUserNameAndRoleId", key = "#userName+'.'+#roleId+'.'+#page")
    public JsonResult findUserByUserNameAndRoleId(String userName, Integer roleId, int page) {
        PageHelper.startPage(page, 5);
        if (userName != null) {
            userName = "%" + userName + "%";
        }
        if (roleId == 0) {
            roleId = null;
        }
        List<User> list = userMapper.findUserByUserNameAndRoleId(userName, roleId);
        unpackingAndPacking(list);
        PageInfo<User> pageInfo = new PageInfo<>(list);
        return ResultTool.success(pageInfo);
    }

    @Override
    public void saveUser(User user, int lastPage) {
        // 将数据录入数据库中
        userMapper.saveUser(user);
        // 删除缓存信息缓存信息
        stringRedisTemplate.opsForValue().set("findUser::" + lastPage, "xxx", 1, TimeUnit.MILLISECONDS);
    }

    @Cacheable(cacheNames = "findUserById", key = "#id")
    public JsonResult findUserById(int id) {
        User user = getById(id);
        unpackingAndPacking(user);
        return ResultTool.success(user);
    }

    @Override
    public void removeUser(int id, int nowPage, int pages) {
        // 1. 逻辑删除数据库
        removeById(id);
        // 2. 删除Redis缓存信息
        ValueOperations value = stringRedisTemplate.opsForValue();
        for (int i = nowPage; i <= pages; i++) {
            value.set("findUser::" + i, "xxx", 1, TimeUnit.MILLISECONDS);
        }
        value.set("findUserById::" + id, "xxx", 1, TimeUnit.MILLISECONDS);
    }

    private void unpackingAndPacking(List<User> list) {
        for (User user : list) {
            // 设置性别
            int gender = user.getGender();
            user.setUserSex(gender == 2 ? "男" : "女");
            // 设置年龄
            user.setUserAge(DateUtil.getAge(user.getBirthday()));
            // 设置角色
            JsonResult role = roleFeign.find(user.getUserRole());
            user.setRole(role);
        }
    }

    private void unpackingAndPacking(User user) {
        // 设置性别
        int gender = user.getGender();
        user.setUserSex(gender == 2 ? "男" : "女");
        // 设置年龄
        user.setUserAge(DateUtil.getAge(user.getBirthday()));
        // 设置角色
        JsonResult role = roleFeign.find(user.getUserRole());
        user.setRole(role);
    }

    @Override
    public void updateUser(User user, int page) {
        // 1. 更新数据库
        userMapper.updateUser(user);
        // 2. 更新缓存
        log.info("开始更新{}页缓存信息！", page);
        ValueOperations value = stringRedisTemplate.opsForValue();
        value.set("findUser::" + page, "xxx", 1, TimeUnit.MILLISECONDS);
        value.set("findUserById::" + user.getId(), "xxx", 1, TimeUnit.MILLISECONDS);
    }

    @Override
    public JsonResult login(String code, String password) {
        User user = userMapper.findUserByUserName(code);
        if (user == null) {
            return ResultTool.fail(ResultCode.USER_ACCOUNT_NOT_EXIST);
        }
        if (!password.equals(user.getUserPassword())) {
            return ResultTool.fail(ResultCode.USER_CREDENTIALS_ERROR);
        }
        String token = JwtConfig.getJwtToken(user);
        stringRedisTemplate.opsForValue().set("token:" + user.getId(), token, 1, TimeUnit.DAYS);
        JsonResult result = ResultTool.success(token);
        result.setErrorMsg(user.getUserName());
        return result;
    }

    @Override
    public JsonResult logout(String token) {
        int id = checkAndGetId(token);
        if (id == -1) {
            return ResultTool.fail();
        }
        stringRedisTemplate.opsForValue().set("token:" + id, "", 1, TimeUnit.MILLISECONDS);
        return ResultTool.success();
    }

    @Override
    public JsonResult findUserIdByToken(String token) {
        int id = checkAndGetId(token);
        if(id==-1){
            return ResultTool.fail();
        }
        return ResultTool.success(id);
    }

    @Override
    public JsonResult is(String token) {
        int id = checkAndGetId(token);
        if (id == -1) {
            return ResultTool.fail();
        }
        String redisToken = stringRedisTemplate.opsForValue().get("token:" + id);
        if (redisToken == null || redisToken.equals("")) {
            return ResultTool.fail();
        }
        if (!redisToken.equals(token)) {
            return ResultTool.fail();
        }
        Claims claims = JwtConfig.parseJWT(token);
        String name = claims.get("name").toString();
        return ResultTool.success(name);
    }

    private int checkAndGetId(String token) {
        if (token == null) {
            return -1;
        }
        boolean b = JwtConfig.checkToken(token);
        if (!b) {
            return -1;
        }
        Claims claims = JwtConfig.parseJWT(token);
        String id = claims.get("id").toString();
        return Integer.parseInt(id);
    }
}
